#include <map.h>
#include <map>
#include <string>

using namespace std;

smap* _sm_create()
{
    smap *m = new smap;
    m->m = new map<string,void*>;
    return m;
}

void _sm_destroy( smap *m )
{
    delete (map<string,void*>*)m->m;
    delete m;
}

int _sm_find( smap *m, const char *key, void **val )
{
    map<string,void*>::iterator it;
    it = ((map<string,void*>*)m->m)->find( key );
    if( it != ((map<string,void*>*)m->m)->end() )
    {
        *val = it->second;
        return 0;
    }
    else
    {
        *val = NULL;
        return -1;
    }
}

int _sm_insert( smap *m, const char *key, void *val )
{
    (*(map<string,void*>*)m->m)[key] = val;
    return 0;
}

int _sm_delete( smap *m, const char *key )
{
    ((map<string,void*>*)m->m)->erase( key );
    return 0;
}

int _sm_for_each( smap *m, void (*func)(void*) )
{
    map<string,void*>::iterator it;
    map<string,void*> *mp = (map<string,void*> *)m->m;
    for( it = mp->begin(); it != mp->end(); ++it )
        func( it->second );
    return mp->size();
}

smap* _im_create()
{
    smap *m = new smap;
    m->m = new map<int64,void*>;
    return m;
}

void _im_destroy( smap *m )
{
    delete (map<int64,void*>*)m->m;
    delete m;
}

int _im_find( smap *m, int64 key, void **val )
{
    map<int64,void*>::iterator it;
    it = ((map<int64,void*>*)m->m)->find( key );
    if( it != ((map<int64,void*>*)m->m)->end() )
    {
        *val = it->second;
        return 0;
    }
    else
    {
        *val = NULL;
        return -1;
    }
}

int _im_insert( smap *m, int64 key, void *val )
{
    (*(map<int64,void*>*)m->m)[key] = val;
    return 0;
}

int _im_delete( smap *m, int64 key )
{
    ((map<int64,void*>*)m->m)->erase( key );
    return 0;
}

int _im_for_each( smap *m, void (*func)(void*) )
{
    map<int64,void*>::iterator it;
    map<int64,void*> *mp = (map<int64,void*> *)m->m;
    for( it = mp->begin(); it != mp->end(); ++it )
        func( it->second );
    return mp->size();
}

smap* _mm_create()
{
    smap *m = new smap;
    m->m = new multimap<string,void*>;
    return m;
}

void _mm_destroy( smap *m )
{
    delete (multimap<string,void*>*)m->m;
    delete m;
}

int _mm_find( smap *m, const char *key, list *val )
{
    multimap<string,void*>::iterator it;
    it = ((multimap<string,void*>*)m->m)->find( key );
    if( it != ((multimap<string,void*>*)m->m)->end() )
    {
        while( it->first == key )
        {
            lt_pushb( val, it->second );
            ++it;
        }
        return 0;
    }
    else
        return -1;
}

int _mm_insert( smap *m, const char *key, void *val )
{
    ((multimap<string,void*>*)m->m)->insert( pair<string,void*>(key, val) );
    return 0;
}

int _mm_delete( smap *m, const char *key )
{
    ((multimap<string,void*>*)m->m)->erase( key );
    return 0;
}

int _mm_for_each( smap *m, void (*func)(void*) )
{
    multimap<string,void*>::iterator it;
    multimap<string,void*> *mp = (multimap<string,void*> *)m->m;
    for( it = mp->begin(); it != mp->end(); ++it )
        func( it->second );
    return mp->size();
}

#ifdef __cplusplus
extern "C"{
#endif

smap* sm_create()
{
    return _sm_create();
}

void sm_destroy( smap *m )
{
    _sm_destroy( m );
}

int sm_find( smap *m, const char *key, void **val )
{
    return _sm_find( m, key, val );
}

int sm_insert( smap *m, const char *key, void *val )
{
    return _sm_insert( m, key, val );
}

int sm_delete( smap *m, const char *key )
{
    return _sm_delete( m, key );
}

int sm_for_each( smap *m, void (*func)(void*) )
{
    return _sm_for_each( m, func );
}

smap* im_create()
{
    return _im_create();
}

void im_destroy( smap *m )
{
    _im_destroy( m );
}

int im_find( smap *m, int64 key, void **val )
{
    return _im_find( m, key, val );
}

int im_insert( smap *m, int64 key, void *val )
{
    return _im_insert( m, key, val );
}

int im_delete( smap *m, int64 key )
{
    return _im_delete( m, key );
}

int im_for_each( smap *m, void (*func)(void*) )
{
    return _im_for_each( m, func );
}

smap* mm_create()
{
    return _mm_create();
}

void mm_destroy( smap *m )
{
    _mm_destroy( m );
}

int mm_find( smap *m, const char *key, list *val )
{
    return _mm_find( m, key, val );
}

int mm_insert( smap *m, const char *key, void *val )
{
    return _mm_insert( m, key, val );
}

int mm_delete( smap *m, const char *key )
{
    return _mm_delete( m, key );
}

int mm_for_each( smap *m, void (*func)(void*) )
{
    return _mm_for_each( m, func );
}

#ifdef __cplusplus
}
#endif
